home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / 68kasm / main.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  8KB  |  318 lines

  1. /******************************************************************************
  2.  * $Id: main.c,v 1.2 1994/09/21 22:29:05 bmott Exp $
  3.  ******************************************************************************
  4.  *
  5.  *        MAIN.C
  6.  *        Main Module for 68000 Assembler
  7.  *
  8.  *    Function: main()
  9.  *        Parses the command line, opens the input file and
  10.  *        output files, and calls processFile() to perform the
  11.  *        assembly, then closes all files. 
  12.  *
  13.  *     Usage: main(argc, argv);
  14.  *        int argc;
  15.  *        char *argv[];
  16.  *
  17.  *      Author: Paul McKee
  18.  *        ECE492    North Carolina State University
  19.  *
  20.  *        Date:    12/13/86
  21.  *
  22.  *   Copyright 1990-1991 North Carolina State University. All Rights Reserved.
  23.  *
  24.  ******************************************************************************
  25.  * $Log: main.c,v $
  26.  * Revision 1.2  1994/09/21  22:29:05  bmott
  27.  * Added support for the INCLUDE directive
  28.  *
  29.  * Revision 1.1  1994/08/30  00:02:09  bmott
  30.  * Initial revision
  31.  *
  32.  *****************************************************************************/
  33.  
  34.  
  35. #include <stdio.h>
  36. #include <ctype.h>
  37. #include "asm.h"
  38.  
  39. char* buildCompleteSourceFile(FILE* currentFile, char* currentFileName,
  40.     FILE* completeFile, int level);
  41.  
  42. extern FILE *inFile;    /* Input file */
  43. extern FILE *listFile;    /* Listing file */
  44. extern FILE *objFile;    /* Object file */
  45. extern char line[256];    /* Source line */
  46. int errorCount, warningCount;    /* Number of errors and warnings */
  47.  
  48.  
  49. extern char listFlag;        /* True if a listing is desired */
  50. extern char objFlag;        /* True if an object code file is desired */
  51. extern char xrefFlag;        /* True if a cross-reference is desired */
  52. extern char cexFlag;        /* True is Constants are to be EXpanded */
  53. extern char absLongFlag;    /* True if all long absolute addresses */
  54.  
  55.  
  56. main(argc, argv)
  57. int argc;
  58. char *argv[];
  59. {
  60. char fileName[64], outName[64], *p, *skipSpace(), *strchr(), *strcpy();
  61. int i;
  62.  
  63. FILE* srcFile;
  64. char *error;
  65.  
  66.     puts("68000 Assembler by PGM\n");
  67.     setFlags(argc, argv, &i);
  68.     /* Check whether a name was specified */
  69.     if (i >= argc) {
  70.         fputs("No input file specified\n\n", stderr);
  71.         help();
  72.         }
  73.     if (!strcmp("?", argv[i]))
  74.         help();
  75.  
  76.  
  77.     /* Open a temp file to build the complete source file in */
  78.     inFile = tmpfile();    
  79.     if (!inFile)
  80.     {
  81.          fputs("Couldn't create temporary file\n", stderr);
  82.         exit();
  83.     }
  84.           
  85.     strcpy(fileName, argv[i]);
  86.     srcFile = fopen(fileName, "r");
  87.         
  88.     if (!srcFile) {
  89.         fputs("Input file not found\n", stderr);
  90.         exit();
  91.         }
  92.  
  93.     error = buildCompleteSourceFile(srcFile, fileName, inFile, 1);
  94.     if (error) {
  95.         fputs(error, stderr);
  96.         exit();
  97.     } 
  98.        
  99.         /* Rewind the in file to the beginning */ 
  100.         rewind(inFile);
  101.  
  102.  
  103.     /****************************************************************
  104.      *                                *
  105.      *    NOTE: The following filename manipulations are        *
  106.      *    intended for VMS filenames only. Other file naming    *
  107.      *    conventions may require changes here.            *
  108.      *                                *
  109.      *    VMS filenames have the form                *
  110.      *                                *
  111.      *        node::device:[dir1.dir2.dir3]filename.ext;vers    *
  112.      *                                *
  113.      *    For use here, we want the listing and object files    *
  114.      *    to be the most recent version in the default        *
  115.      *    directory, so we strip off the node, device, and    *
  116.      *    directory names, extension, and version number, then    *
  117.      *    append the appropriate file extension (.LIS or .H68)    *
  118.      *    for each file.                         *
  119.      *                                *
  120.      ****************************************************************/
  121.  
  122.     /* Process output file names in their own buffer */
  123.     strcpy(outName, fileName);
  124.  
  125.     /* Delete version number from output file names */
  126.     p = strchr(outName, ';');
  127.     if (p)
  128.         *p = '\0';
  129.  
  130.     /* Remove directory name from output file names */
  131.     p = outName + strlen(outName);
  132.     while (p >= outName && *p != ':' && *p != ']')
  133.         p--;
  134.     if (p >= outName)
  135.         strcpy(outName, ++p);
  136.     
  137.     /* Change extension to .LIS */
  138.     p = strchr(outName, '.');
  139.     if (!p)
  140.         p = outName + strlen(outName);
  141.  
  142.     if (listFlag) {
  143.         strcpy(p, ".LIS");
  144. /*        printf("Listing filename is \"%s\"\n", outName); */
  145.         initList(outName);
  146.         }
  147.  
  148.     if (objFlag) {
  149.         strcpy(p, ".H68");
  150. /*        printf("Object filename is \"%s\"\n", outName); */
  151.         initObj(outName);
  152.     }
  153.  
  154.     /* Assemble the file */
  155.     processFile();
  156.  
  157.     /* Close files and print error and warning counts */
  158.     fclose(inFile);
  159.     if (listFlag) {
  160.         putc('\n', listFile);
  161.         if (errorCount > 0)
  162.             fprintf(listFile, "%d error%s detected\n", errorCount,
  163.                 (errorCount > 1) ? "s" : "");
  164.         else
  165.             fprintf(listFile, "No errors detected\n");
  166.         if (warningCount > 0)
  167.             fprintf(listFile, "%d warning%s generated\n", warningCount,
  168.                 (warningCount > 1) ? "s" : "");
  169.         else
  170.             fprintf(listFile, "No warnings generated\n");
  171.         fclose(listFile);
  172.         }
  173.     if (objFlag)
  174.         finishObj();
  175.     if (errorCount > 0)
  176.         fprintf(stderr, "%d error%s detected\n", errorCount,
  177.             (errorCount > 1) ? "s" : "");
  178.     else
  179.         fprintf(stderr, "No errors detected\n");
  180.     if (warningCount > 0)
  181.         fprintf(stderr, "%d warning%s generated\n", warningCount,
  182.             (warningCount > 1) ? "s" : "");
  183.     else
  184.         fprintf(stderr, "No warnings generated\n");
  185. }
  186.  
  187.  
  188. strcap(d, s)
  189. char *d, *s;
  190. {
  191. char capFlag;
  192.  
  193.     capFlag = TRUE;
  194.     while (*s) {
  195.         if (capFlag)
  196.             *d = toupper(*s);
  197.         else
  198.             *d = *s;
  199.         if (*s == '\'')
  200.             capFlag = !capFlag;
  201.         d++;
  202.         s++;
  203.         }
  204.     *d = '\0';
  205. }
  206.  
  207.  
  208. char *skipSpace(p)
  209. char *p;
  210. {
  211.     while (isspace(*p))
  212.         p++;
  213.     return p;
  214. }
  215.  
  216.  
  217. setFlags(argc, argv, argi)
  218. int argc;
  219. char *argv[];
  220. int *argi;
  221. {
  222. int option;
  223.  
  224.     while ((option = getoptions(argc, argv, "clna", argi)) != EOF) {
  225.         switch (option) {
  226.             case 'c' : cexFlag = TRUE; break;
  227.             case 'h' : help(); break;
  228.             case 'l' : listFlag = TRUE; break;
  229.             case 'n' : objFlag = FALSE; break;
  230.             case '?' : help(); break;
  231.             case 'a' : absLongFlag = TRUE; break;
  232.             }
  233.         }
  234. }
  235.  
  236.  
  237. /**********************************************************************
  238.  *
  239.  *    Function getoptions() scans the command line arguments passed
  240.  *    via argc and argv for options of the form "-x". It returns
  241.  *    the letters of the options, one per call, until all the
  242.  *    options have been returned; it then returns EOF. The argi
  243.  *    argument is set to the number of the argv string that
  244.  *    is currently being examined.
  245.  *
  246.  *********************************************************************/
  247.  
  248. int getoptions(argc, argv, optstring, argi)
  249. int argc;
  250. char *argv[];
  251. char *optstring;
  252. int *argi;
  253. {
  254. static char *scan = NULL;    /* Scan pointer */
  255. static int optind = 0;        /* argv index */
  256.  
  257. char c;
  258. char *place;
  259. char *strchr();
  260.  
  261.     if (scan == NULL || *scan == '\0') {
  262.         if (optind == 0)
  263.             optind++;
  264.  
  265.         if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') {
  266.             *argi = optind;
  267.             return(EOF);
  268.             }
  269.         if (strcmp(argv[optind], "--")==0) {
  270.             optind++;
  271.             *argi = optind;
  272.             return(EOF);
  273.         }
  274.  
  275.         scan = argv[optind]+1;
  276.         optind++;
  277.     }
  278.  
  279.     c = *scan++;
  280.     place = strchr(optstring, c);
  281.  
  282.     if (place == NULL || c == ':') {
  283.         fprintf(stderr, "Unknown option -%c\n", c);
  284.         *argi = optind;
  285.         return('?');
  286.     }
  287.  
  288.     place++;
  289.     if (*place == ':') {
  290.         if (*scan != '\0')
  291.             scan = NULL;
  292.         else
  293.             optind++;
  294.     }
  295.  
  296.     *argi = optind;
  297.     return(c);
  298. }
  299.  
  300.  
  301. /**********************************************************************
  302.  *
  303.  *    Function help() prints out a usage explanation if a bad
  304.  *    option is specified or no filename is given.
  305.  *
  306.  *********************************************************************/
  307.  
  308. help()
  309. {
  310.     puts("Usage: asm [-clna] infile.ext\n");
  311.     puts("Options: -c  Show full constant expansions for DC directives");
  312.     puts("         -l  Produce listing file (infile.lis)");
  313.     puts("         -n  Produce NO object file (infile.h68)");
  314.     puts("         -a  Produce long word absolute addresses only (infile.h68)");
  315.     exit();
  316. }
  317.  
  318.